home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Technology Seed / Jan. '98 ATS.toast / NavServices1.0b3 / Navigation Services SDK / Examples / Sampler / Sampler ƒ / menus.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-12  |  22.2 KB  |  874 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        menus.c
  3.  
  4.     Copyright:    © 1997-1998 by Apple Computer, Inc., all rights reserved.
  5.  
  6. */
  7.  
  8. #pragma segment AppSeg
  9.  
  10. #ifndef __SCRAP__
  11. #include <Scrap.h>
  12. #endif
  13.  
  14. #ifndef __DEVICES__
  15. #include <Devices.h>
  16. #endif
  17.  
  18. #ifndef __TOOLUTILS__
  19. #include <ToolUtils.h>
  20. #endif
  21.  
  22.  
  23. #ifndef Common_Defs
  24. #include "Common.h"
  25. #endif
  26.  
  27. extern Document* gDocumentList[kMaxDocumentCount];
  28. extern short    gDocumentCount;
  29. extern short    gCanUndoDrag;
  30. extern short    gQuit, gQuitting;
  31. extern Boolean    gNavServicesExists;
  32.  
  33. // prototypes:
  34. void SetItemEnable( MenuHandle theMenu, short theItem, short enable );
  35. short DoPaste( );
  36. void DoAbout( );
  37. void DoSelectDictionary( );
  38. void DoSelectDirectory( );
  39. void DoSelectObject( );
  40. void DoSelectVolume( );
  41. void DoCreateFolder( );
  42. void DoCustomOpen( );
  43.  
  44. // for customization:
  45. pascal void myCustomEventProc( NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, NavCallBackUserData callBackUD);
  46. void HandleCustomMouseDown( NavCBRecPtr callBackParms );
  47. void HandleCommandPopup( ControlHandle thePopup, NavCBRecPtr callBackParms );
  48.  
  49.  
  50. // custom dialog item:
  51. #define kControlListID    132
  52. #define kPopupCommand     1
  53.  
  54. // the requested dimensions for our customization area:
  55. #define kCustomWidth    100
  56. #define kCustomHeight    40
  57.                 
  58. // customization globals:
  59. Handle         gDitlList;
  60. MenuHandle     gPopupMenu;
  61. short         gLastTryWidth;
  62. short         gLastTryHeight;
  63.  
  64.                         
  65. // *****************************************************************************
  66. // *
  67. // *    SetItemEnable()
  68. // *
  69. // *****************************************************************************
  70. void SetItemEnable(MenuHandle theMenu, short theItem, short enable)
  71. {
  72.     if (enable)
  73.         EnableItem(theMenu,theItem);
  74.     else
  75.         DisableItem(theMenu,theItem);
  76. }
  77.  
  78.  
  79. // *****************************************************************************
  80. // *
  81. // *    AdjustMenus()
  82. // *
  83. // *****************************************************************************
  84. void AdjustMenus()
  85. {    
  86.     MenuHandle    theMenu;
  87.     Document*    theDocument;
  88.     short        teSelection = 0;
  89.     Str255        theStr;
  90.  
  91.     theDocument = IsDocumentWindow((WindowPtr)FrontWindow());
  92.     
  93.     if (theDocument->theTE != NULL)
  94.         teSelection = (theDocument) && ((**(theDocument->theTE)).selStart != (**(theDocument->theTE)).selEnd);
  95.  
  96.     theMenu = GetMenuHandle(idFileMenu);
  97.  
  98.     SetItemEnable(theMenu,NewItem,gDocumentCount < kMaxDocumentCount);
  99.     SetItemEnable(theMenu,OpenItem,gDocumentCount < kMaxDocumentCount);
  100.  
  101.     SetItemEnable(theMenu,CloseItem,theDocument != 0L);
  102.     SetItemEnable(theMenu,SaveItem,(theDocument) && (theDocument->dirty));
  103.     SetItemEnable(theMenu,RevertItem,(theDocument) && (theDocument->dirty) && (theDocument->fRefNum));
  104.     SetItemEnable(theMenu,SaveACopyItem,theDocument != 0L);
  105.     SetItemEnable(theMenu,DictionaryItem,gNavServicesExists);
  106.  
  107.     theMenu = GetMenuHandle(idEditMenu);
  108.  
  109.     GetIndString(theStr,MenuStringsID,gCanUndoDrag);
  110.     SetMenuItemText(theMenu,iUndo,theStr);
  111.     SetItemEnable(theMenu,iUndo,gCanUndoDrag != slCantUndo);
  112.  
  113.     SetItemEnable(theMenu,iCut,teSelection);
  114.     SetItemEnable(theMenu,iCopy,teSelection);
  115.     SetItemEnable(theMenu,iPaste,theDocument != 0L);
  116.     SetItemEnable(theMenu,iClear,teSelection);
  117.     SetItemEnable(theMenu,iSelectAll,theDocument != 0L);
  118.  
  119.     theMenu = GetMenuHandle(idUtilsMenu);
  120.     SetItemEnable(theMenu,iSelectDir,gNavServicesExists);
  121.     SetItemEnable(theMenu,iSelectVol,gNavServicesExists);
  122.     SetItemEnable(theMenu,iSelectObject,gNavServicesExists);
  123.     SetItemEnable(theMenu,iCreateFolder,gNavServicesExists);
  124.     SetItemEnable(theMenu,iCustomOpen,gNavServicesExists);
  125. }
  126.  
  127.  
  128. // *****************************************************************************
  129. // *
  130. // *    DoPaste()
  131. // *
  132. // *****************************************************************************
  133. short DoPaste()
  134. {    
  135.     long    size, offset;
  136.     Handle    theData;
  137.  
  138.     size = GetScrap(0L,'UPRC',&offset);
  139.  
  140.     if (size <= 0)
  141.         return(0);
  142.  
  143.     theData = NewHandle(size);
  144.     GetScrap(theData,'UPRC',&offset);
  145.  
  146.     HLock(theData);
  147.     PutScrap(size,'test',*theData);
  148.  
  149.     HUnlock(theData);
  150.     DisposeHandle(theData);
  151.  
  152.     return noErr;
  153. }
  154.  
  155.  
  156. // *****************************************************************************
  157. // *
  158. // *    DoSelectDictionary()
  159. // *    
  160. // *****************************************************************************
  161. void DoSelectDictionary()
  162. {    
  163.     NavReplyRecord        theReply;
  164.     NavDialogOptions    dialogOptions;
  165.     OSErr                theErr = noErr;
  166.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  167.     NavTypeListHandle    openList = NULL;
  168.     
  169.     // use the default location for the dialog:
  170.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  171.  
  172.     GetIndString(dialogOptions.message,rAppStringsID,sChooseFile);
  173.  
  174.     dialogOptions.preferenceKey = kSelectFilePrefKey;
  175.     
  176.     openList = (NavTypeListHandle)GetResource(kOpenRsrcType,kOpenRsrcID2);
  177.         
  178.     theErr = NavChooseFile(    NULL,
  179.                             &theReply,
  180.                             &dialogOptions,
  181.                             eventUPP,
  182.                             NULL,
  183.                             NULL,
  184.                             openList,
  185.                             (NavCallBackUserData)&gDocumentList);
  186.     
  187.     DisposeRoutineDescriptor(eventUPP);
  188.     
  189.     if ((theReply.validRecord)&&(theErr == noErr))
  190.         {
  191.         // grab the target FSSpec from the AEDesc:    
  192.         FSSpec    finalFSSpec;    
  193.         AEDesc     resultDesc;
  194.  
  195.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  196.         if (theErr == noErr)
  197.             {
  198.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));    
  199.             // 'finalFSSpec' is the chosen file…
  200.             }
  201.             
  202.         theErr = NavDisposeReply(&theReply);
  203.         }
  204.     
  205.     if (openList != NULL)
  206.         DisposeHandle((Handle)openList);
  207. }
  208.  
  209.  
  210. // *****************************************************************************
  211. // *
  212. // *    DoSelectDirectory()
  213. // *    
  214. // *****************************************************************************
  215. void DoSelectDirectory()
  216. {    
  217.     NavReplyRecord        theReply;
  218.     NavDialogOptions    dialogOptions;
  219.     OSErr                theErr = noErr;
  220.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  221.     
  222.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  223.     
  224.     GetIndString(dialogOptions.message,rAppStringsID,sChooseFolder);
  225.     
  226.     dialogOptions.preferenceKey = kSelectFolderPrefKey;
  227.     
  228.     theErr = NavChooseFolder(    NULL,
  229.                                 &theReply,
  230.                                 &dialogOptions,
  231.                                 eventUPP,
  232.                                 NULL,
  233.                                 (NavCallBackUserData)&gDocumentList);
  234.     
  235.     DisposeRoutineDescriptor(eventUPP);
  236.  
  237.     if ((theReply.validRecord)&&(theErr == noErr))
  238.         {
  239.         // grab the target FSSpec from the AEDesc:    
  240.         FSSpec    finalFSSpec;    
  241.         AEDesc     resultDesc;
  242.  
  243.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  244.         if (theErr == noErr)
  245.             {
  246.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));    
  247.             // 'finalFSSpec' is the selected directory…
  248.             }
  249.         
  250.         theErr = NavDisposeReply(&theReply);
  251.         }
  252. }
  253.  
  254.  
  255. // *****************************************************************************
  256. // *
  257. // *    DoSelectObject()
  258. // *    
  259. // *****************************************************************************
  260. void DoSelectObject()
  261. {    
  262.     NavReplyRecord        theReply;
  263.     NavDialogOptions    dialogOptions;
  264.     OSErr                theErr = noErr;
  265.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  266.     
  267.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  268.     
  269.     GetIndString(dialogOptions.message,rAppStringsID,sChooseObject);
  270.     
  271.     dialogOptions.preferenceKey = kSelectObjectPrefKey;
  272.     
  273.     theErr = NavChooseObject(    NULL,
  274.                                 &theReply,
  275.                                 &dialogOptions,
  276.                                 eventUPP,
  277.                                 NULL,
  278.                                 (NavCallBackUserData)&gDocumentList);
  279.     
  280.     DisposeRoutineDescriptor(eventUPP);
  281.  
  282.     if ((theReply.validRecord)&&(theErr == noErr))
  283.         {
  284.         // grab the target FSSpec from the AEDesc:    
  285.         FSSpec    finalFSSpec;    
  286.         AEDesc     resultDesc;
  287.  
  288.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  289.         if (theErr == noErr)
  290.             {
  291.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));    
  292.             // 'finalFSSpec' is the selected directory…
  293.             }
  294.         
  295.         theErr = NavDisposeReply(&theReply);
  296.         }
  297. }
  298.  
  299.  
  300.  
  301. // *****************************************************************************
  302. // *
  303. // *    DoSelectVolume()
  304. // *    
  305. // *****************************************************************************
  306. void DoSelectVolume()
  307. {    
  308.     NavReplyRecord        theReply;
  309.     NavDialogOptions    dialogOptions;
  310.     OSErr                theErr = noErr;
  311.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  312.     
  313.     // use the default location for the dialog:
  314.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  315.     
  316.     GetIndString(dialogOptions.message,rAppStringsID,sChooseVolume);
  317.  
  318.     dialogOptions.preferenceKey = kSelectVolumePrefKey;
  319.     
  320.     theErr = NavChooseVolume(    NULL,
  321.                                 &theReply,
  322.                                 &dialogOptions,
  323.                                 eventUPP,
  324.                                 NULL,
  325.                                 (NavCallBackUserData)&gDocumentList);
  326.     if ((theReply.validRecord)&&(theErr == noErr))
  327.         {
  328.         // grab the target FSSpec from the AEDesc:    
  329.         FSSpec    finalFSSpec;    
  330.         AEDesc     resultDesc;
  331.  
  332.         // there is only one selection here we get only the first AEDesc:
  333.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  334.         if (theErr == noErr)
  335.             {
  336.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));
  337.             // 'finalFSSpec' is the chosen volume…
  338.             }
  339.         
  340.         theErr = NavDisposeReply(&theReply);
  341.         }
  342.         
  343.     DisposeRoutineDescriptor(eventUPP);
  344. }
  345.  
  346.  
  347. // *****************************************************************************
  348. // *
  349. // *    DoCreateFolder()
  350. // *    
  351. // *****************************************************************************
  352. void DoCreateFolder()
  353. {    
  354.     NavReplyRecord        theReply;
  355.     NavDialogOptions    dialogOptions;
  356.     OSErr                theErr = noErr;
  357.     NavEventUPP            eventUPP = NewNavEventProc(myEventProc);
  358.     
  359.     // use the default location for the dialog:
  360.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  361.     
  362.     GetIndString(dialogOptions.message,rAppStringsID,sCreateFolder);
  363.  
  364.     dialogOptions.preferenceKey = kNewFolderPrefKey;
  365.     
  366.     theErr = NavNewFolder(    NULL,
  367.                             &theReply,
  368.                             &dialogOptions,
  369.                             eventUPP, 
  370.                             (NavCallBackUserData)&gDocumentList);
  371.     if (theReply.validRecord)
  372.         {
  373.         // grab the target FSSpec from the AEDesc:    
  374.         FSSpec    finalFSSpec;    
  375.         AEDesc     resultDesc;
  376.  
  377.         // there is only one selection here so we get the first AEDesc:
  378.         theErr = AECoerceDesc(&(theReply.selection),typeFSS,&resultDesc);
  379.         if (theErr == noErr)
  380.             {
  381.             BlockMove(*resultDesc.dataHandle,(void*)&finalFSSpec,sizeof(FSSpec));
  382.             // 'finalFSSpec' is the newly created folder…
  383.             }
  384.  
  385.         theErr = NavDisposeReply(&theReply);
  386.         }
  387. }
  388.  
  389.  
  390. // *****************************************************************************
  391. // *
  392. // *    HandleCommandPopup()
  393. // *    
  394. // *****************************************************************************
  395. void HandleCommandPopup(ControlHandle thePopup, NavCBRecPtr callBackParms)
  396. {
  397.     OSErr     theErr = noErr;
  398.     short     selection = 0;
  399.     
  400.     selection = GetControlValue(thePopup)-1;
  401.     switch (selection)
  402.         {                                
  403.         case kNavCtlShowDesktop:
  404.         case kNavCtlScrollHome:
  405.         case kNavCtlScrollEnd:
  406.         case kNavCtlPageUp:
  407.         case kNavCtlPageDown:
  408.             theErr = NavCustomControl(callBackParms->context,selection,NULL);
  409.             break;
  410.         
  411.         case kNavCtlShowSelection:
  412.             theErr = NavCustomControl(callBackParms->context,kNavCtlShowSelection,NULL);
  413.             break;
  414.         
  415.         case kNavCtlOpenSelection:
  416.             {
  417.             AEDesc itemToOpen;
  418.             theErr = NavCustomControl(callBackParms->context,kNavCtlOpenSelection,&itemToOpen);
  419.             if (itemToOpen.descriptorType == typeFSS)
  420.                 {    
  421.                 // you may open the file as described by 'itemToOpen', or do whatever you want with it:
  422.                 AEDisposeDesc(&itemToOpen);
  423.                 }
  424.             break;
  425.             }
  426.             
  427.         case kNavCtlCancel:
  428.             theErr = NavCustomControl(callBackParms->context,kNavCtlCancel,NULL);
  429.             break;
  430.     
  431.         case kNavCtlAccept:
  432.             theErr = NavCustomControl(callBackParms->context,kNavCtlAccept,NULL);
  433.             break;
  434.         }
  435. }
  436.  
  437.  
  438. void HandleCustomMouseDown(NavCBRecPtr callBackParms)
  439. {
  440.     OSErr            theErr = noErr;
  441.     ControlHandle    whichControl;                
  442.     Point             where = callBackParms->eventData.event->where;    
  443.     short            theItem = 0;    
  444.     UInt16             firstItem = 0;
  445.     short            realItem = 0;
  446.     short            partCode = 0;
  447.         
  448.     GlobalToLocal(&where);
  449.     theItem = FindDialogItem(callBackParms->window,where);    // get the item number of the control
  450.     partCode = FindControl(where,callBackParms->window,&whichControl);    // get the control itself
  451.     
  452.     // ask NavServices for the first custom control's ID:
  453.     if (callBackParms->context != 0)    // always check to see if the context is correct
  454.         {
  455.         theErr = NavCustomControl(callBackParms->context,kNavCtlGetFirstControlID,&firstItem);    
  456.         realItem = theItem - firstItem + 1;        // map it to our DITL constants:    
  457.         }
  458.                 
  459.     if (realItem == kPopupCommand)
  460.         HandleCommandPopup(whichControl,callBackParms);
  461. }                    
  462.  
  463.  
  464. // *****************************************************************************
  465. // *
  466. // *    myEventProc()    
  467. // *
  468. // *****************************************************************************
  469. pascal void myCustomEventProc(    NavEventCallbackMessage callBackSelector, 
  470.                                 NavCBRecPtr callBackParms, 
  471.                                 NavCallBackUserData callBackUD)
  472. {
  473.     OSErr        theErr = noErr;
  474.     WindowPtr    pWindow = NULL;
  475.     Document**    docList;
  476.     Document*    theDoc = NULL;
  477.     short         index = 0;
  478.  
  479.     if (callBackUD != 0)
  480.         switch (callBackSelector)
  481.             {
  482.             case kNavCBEvent:
  483.                 {
  484.                 docList = (Document**)callBackUD;
  485.                 if (docList != NULL)
  486.                     switch (callBackParms->eventData.event->what)
  487.                         {
  488.                         case mouseDown:
  489.                             HandleCustomMouseDown(callBackParms);
  490.                             break;
  491.                         
  492.                         case updateEvt:
  493.                             pWindow = (WindowPtr)callBackParms->eventData.event->message;
  494.                             theDoc = docList[index];
  495.                             if (theDoc != NULL)
  496.                                 {
  497.                                 while ((theDoc->theWindow != pWindow) && (docList[index] != NULL))
  498.                                     {
  499.                                     index++;
  500.                                     theDoc = docList[index];
  501.                                     }
  502.                                 theDoc = docList[index];
  503.                                 if (theDoc != NULL)
  504.                                     UpdateWindow(theDoc);
  505.                                 }
  506.                             break;
  507.  
  508.                         default:
  509.                             break;
  510.                         }
  511.                 break;
  512.                 }
  513.     
  514.             case kNavCBCustomize:
  515.                 {                                
  516.                 // here are the desired dimensions for our custom area:
  517.                 short neededWidth = callBackParms->customRect.left + kCustomWidth;
  518.                 short neededHeight = callBackParms->customRect.top + kCustomHeight;
  519.                 
  520.                 // check to see if this is the first round of negotiations:
  521.                 if ((callBackParms->customRect.right == 0) && (callBackParms->customRect.bottom == 0))
  522.                     {
  523.                     // it is, so tell NavServices what dimensions we want:
  524.                     callBackParms->customRect.right = neededWidth;
  525.                     callBackParms->customRect.bottom = neededHeight;
  526.                     }
  527.                 else
  528.                     {
  529.                     // we are in the middle of negotiating:
  530.                     if (gLastTryWidth != callBackParms->customRect.right)
  531.                         if (callBackParms->customRect.right < neededWidth)    // is NavServices width too small for us?
  532.                             callBackParms->customRect.right = neededWidth;
  533.  
  534.                     if (gLastTryHeight != callBackParms->customRect.bottom)    // is NavServices height too small for us?
  535.                         if (callBackParms->customRect.bottom < neededHeight)
  536.                             callBackParms->customRect.bottom = neededHeight;
  537.                     }
  538.                 
  539.                 // remember our last size so the next time we can re-negotiate:
  540.                 gLastTryWidth = callBackParms->customRect.right;
  541.                 gLastTryHeight = callBackParms->customRect.bottom;    
  542.                 break;
  543.                 }
  544.                 
  545.             case kNavCBStart:
  546.                 {
  547.                 short    itemType;
  548.                 Rect    itemRect;
  549.                 Handle    itemH;
  550.                 UInt16     firstItem = 0;    
  551.                 short    realItem = 0;
  552.                 
  553.                 // add the rest of the custom controls via the DITL resource list:
  554.                 gDitlList = GetResource('DITL',kControlListID);
  555.                 if ((gDitlList != NULL)&&(ResError() == noErr))
  556.                     if ((theErr = NavCustomControl(callBackParms->context,kNavCtlAddControlList,gDitlList)) == noErr)
  557.                         {
  558.                         theErr = NavCustomControl(callBackParms->context,kNavCtlGetFirstControlID,&firstItem);    // ask NavServices for our first control ID
  559.                                 
  560.                         // set the command popup selection:
  561.                         realItem = firstItem + kPopupCommand;
  562.                         GetDialogItem(callBackParms->window,realItem,&itemType,&itemH,&itemRect);
  563.                         SetControlValue((ControlHandle)itemH,1);
  564.                         }
  565.                     
  566.                 // the dialog is starting up, let's override the default popup menu selection:
  567.                 UInt16 itemToSelect = kNavAllReadableFiles;
  568.                 theErr = NavCustomControl(callBackParms->context,kNavCtlSelectAllType,&itemToSelect);
  569.                 break;
  570.                 }
  571.                 
  572.             case kNavCBTerminate:
  573.                 // release our appended popup menu:
  574.                 if (gDitlList)
  575.                     ReleaseResource(gDitlList);        
  576.                 if (gPopupMenu)
  577.                     DisposeMenu(gPopupMenu);        
  578.                 break;
  579.             }
  580. }
  581.  
  582.  
  583. // *****************************************************************************
  584. // *
  585. // *    DoCustomOpen()
  586. // *    
  587. // *****************************************************************************
  588. void DoCustomOpen()
  589. {    
  590.     NavReplyRecord        theReply;
  591.     NavDialogOptions    dialogOptions;
  592.     OSErr                theErr = noErr;
  593.     NavTypeListHandle    typeList = NULL;
  594.     long                count = 0;
  595.     NavEventUPP            eventUPP = NewNavEventProc(myCustomEventProc);
  596.     
  597.     // default behavior for browser and dialog:
  598.     theErr = NavGetDefaultDialogOptions(&dialogOptions);
  599.  
  600.     GetIndString((unsigned char*)&dialogOptions.clientName,rAppStringsID,sApplicationName);
  601.     
  602.     typeList = (NavTypeListHandle)GetResource(kOpenRsrcType,kOpenRsrcID);
  603.  
  604.     theErr = NavGetFile(NULL,    // use system's default location
  605.                         &theReply,
  606.                         &dialogOptions,
  607.                         eventUPP,
  608.                         NULL,    // no custom previews
  609.                         NULL,
  610.                         typeList,
  611.                         (NavCallBackUserData)&gDocumentList);
  612.  
  613.     DisposeRoutineDescriptor(eventUPP);
  614.  
  615.     if (theReply.validRecord && theErr == noErr)
  616.         {
  617.         // since we allow for multiple objects to be returned,
  618.         // grab the target FSSpecs from 'theReply.fileRef' list for opening:    
  619.         FSSpec    finalFSSpec;    
  620.         AEDesc     resultDesc;
  621.         FInfo    fileInfo;
  622.  
  623.         // we are ready to open the document(s), grab information about each file for opening:
  624.         theErr = AECountItems(&(theReply.selection),&count);
  625.         for (long index=1;index<=count;index++)
  626.             {
  627.             resultDesc.dataHandle = 0L;
  628.             theErr = AEGetNthDesc(&(theReply.selection),index,typeFSS,NULL,&resultDesc);
  629.             if (theErr == noErr)
  630.                 {
  631.                 BlockMoveData(*resultDesc.dataHandle,&finalFSSpec,sizeof(FSSpec));
  632.             
  633.                 // decide if the doc we are opening is a 'PICT' or 'TEXT':
  634.                 theErr = FSpGetFInfo(&finalFSSpec,&fileInfo);
  635.                 if (theErr == noErr)
  636.                     {
  637.                     if (fileInfo.fdType == kFileType)
  638.                         (void)DoOpenFile(&finalFSSpec,false);
  639.                     else
  640.                         if (fileInfo.fdType == kFileTypePICT)
  641.                             (void)DoOpenFile(&finalFSSpec,true);
  642.                         else
  643.                             {
  644.                             // error:
  645.                             // if we got this far, the document is a type we can't open and
  646.                             // (most likely) built-in translation was turned off.
  647.                             // You can alert the user that this returned selection or file spec
  648.                             // needs translation.
  649.                             }
  650.                     }
  651.                 theErr = AEDisposeDesc(&resultDesc);
  652.                 }
  653.             }
  654.         
  655.         theErr = NavDisposeReply(&theReply);    // clean up after ourselves    
  656.         }
  657.  
  658.     if (typeList != NULL)
  659.         ReleaseResource((Handle)typeList);
  660. }
  661.  
  662.  
  663. // *****************************************************************************
  664. // *
  665. // *    DoAbout()
  666. // *    
  667. // *****************************************************************************
  668. void DoAbout()
  669. {
  670.     GrafPtr        savePort;
  671.     DialogPtr    aboutDialog;
  672.     short        itemHit = 0;
  673.     Handle        itemH;
  674.     short        itemType;
  675.     Rect        itemRect;
  676.     
  677.     SetCursor(&qd.arrow);
  678.     aboutDialog = GetNewDialog(rAboutID,nil,(WindowRef)-1);
  679.     
  680.     GetPort(&savePort);
  681.  
  682.     SetPort((GrafPtr)aboutDialog);
  683.  
  684.     AdornButton(aboutDialog,dOK);
  685.  
  686.     GetDialogItem(aboutDialog,iIconSuite,&itemType,&itemH,&itemRect);
  687.     DrawIconSuite(rIconSuite,itemRect);
  688.                     
  689.     do ModalDialog(nil,&itemHit);
  690.  
  691.     while(itemHit != dOK);
  692.     
  693.     SetPort(savePort);
  694.     DisposeDialog(aboutDialog);
  695. }
  696.  
  697.  
  698. // *****************************************************************************
  699. // *
  700. // *    DoMenuCommand()
  701. // *
  702. // *****************************************************************************
  703. void DoMenuCommand(long select)
  704. {    
  705.     short        theMenuID, theItem;
  706.     MenuHandle    theMenu;
  707.     Str255        theName;
  708.     WindowPtr    theWindow;
  709.     Document*    theDocument = nil;
  710.     OSStatus    theErr = noErr;
  711.  
  712.     gCanUndoDrag = slUndoDrag;
  713.     AdjustMenus();
  714.     
  715.     theDocument = IsDocumentWindow(theWindow = (WindowPtr)FrontWindow());
  716.  
  717.     theItem   = LoWord(select);
  718.     theMenuID = HiWord(select);
  719.     theMenu   = GetMenuHandle(theMenuID);
  720.     switch(theMenuID)
  721.         {
  722.         case idAppleMenu:
  723.             switch(theItem)
  724.                 {
  725.                 case AboutItem:
  726.                     DoAbout();
  727.                     break;
  728.                 default:
  729.                     GetMenuItemText(GetMenuHandle(idAppleMenu),theItem,(unsigned char*)&theName);
  730.                     OpenDeskAcc(theName);
  731.                 }
  732.             break;
  733.             
  734.         case idFileMenu:
  735.             switch(theItem)
  736.                 {
  737.                 case NewItem:
  738.                     DoNewDocument(false);
  739.                     AdjustMenus();
  740.                     break;
  741.                     
  742.                 case OpenItem:
  743.                     if (gNavServicesExists)
  744.                         (void)DoOpenDocument();
  745.                     else    
  746.                         (void)DoOpenDocumentTheOldWay();
  747.                     AdjustMenus();        
  748.                     break;
  749.                     
  750.                 case CloseItem:
  751.                     if (theDocument)
  752.                         {
  753.                         CloseDocument(theDocument,false);
  754.                         AdjustMenus();
  755.                         DrawMenuBar();
  756.                         }
  757.                     break;
  758.                     
  759.                 case SaveItem:
  760.                     if (theDocument)
  761.                         DoSaveDocument(theDocument);
  762.                     break;
  763.                 
  764.                 case SaveACopyItem:
  765.                     if (theDocument)
  766.                         {
  767.                         if (gNavServicesExists)
  768.                             (void)SaveACopyDocument(theDocument);
  769.                         else
  770.                             (void)SaveACopyDocumentTheOldWay(theDocument);
  771.                         }
  772.                     break;
  773.     
  774.                 case RevertItem:
  775.                     DisableUndoDrag();
  776.                     if (theDocument)
  777.                         {
  778.                         if (gNavServicesExists)
  779.                             DoRevertDocument(theDocument);
  780.                         else
  781.                             DoRevertDocumentTheOldWay(theDocument);
  782.                         }
  783.                     break;
  784.  
  785.                 case DictionaryItem:
  786.                     DoSelectDictionary();
  787.                     break;
  788.  
  789.                 case QuitItem:
  790.                     gQuitting = true;
  791.                     while ((gQuitting) && (theDocument = IsDocumentWindow((WindowPtr)FrontWindow())))
  792.                         CloseDocument(theDocument,true);
  793.                     if (gQuitting)
  794.                         gQuit = true;
  795.                     break;
  796.                 }
  797.             break;
  798.             
  799.         case idEditMenu:
  800.             switch(theItem)
  801.                 {
  802.                 case iUndo:
  803.                     DoUndoDrag();
  804.                     break;
  805.                     
  806.                 case iCut:
  807.                     if ((theDocument)&&(theDocument->theTE != NULL))
  808.                         {
  809.                         DisableUndoDrag();
  810.                         myTECut(theDocument->theTE);
  811.                         }
  812.                     break;
  813.                     
  814.                 case iCopy:
  815.                     if (theDocument)
  816.                         TECopy(theDocument->theTE);
  817.                     break;
  818.                     
  819.                 case iPaste:
  820.                     if ((theDocument)&&(theDocument->theTE != NULL))
  821.                         if (!DoPaste())
  822.                             {
  823.                             DisableUndoDrag();
  824.                             myTEPaste(theDocument->theTE,0L,0L);
  825.                             }
  826.                     break;
  827.                     
  828.                 case iClear:
  829.                     if ((theDocument)&&(theDocument->theTE != NULL))
  830.                         {
  831.                         DisableUndoDrag();
  832.                         TEDelete(theDocument->theTE);
  833.                         }
  834.                     break;
  835.                     
  836.                 case iSelectAll:
  837.                     if ((theDocument)&&(theDocument->theTE != NULL))
  838.                         DoSelectAllDocument(theDocument);
  839.                     break;
  840.                 }
  841.             break;
  842.  
  843.         case idUtilsMenu:
  844.             switch (theItem)
  845.                 {
  846.                 case iSelectDir:
  847.                     DoSelectDirectory();
  848.                     break;
  849.                 case iSelectVol:
  850.                     DoSelectVolume();
  851.                     break;
  852.                 case iSelectObject:
  853.                     DoSelectObject();
  854.                     break;
  855.                 case iCreateFolder:
  856.                     DoCreateFolder();
  857.                     break;
  858.                 case iCustomOpen:
  859.                     DoCustomOpen();
  860.                     break;
  861.                 }
  862.             break;
  863.         }        
  864.  
  865.     if (theDocument = IsDocumentWindow((WindowPtr)FrontWindow()))
  866.         if (theDocument->theTE != NULL)
  867.             TEGetHiliteRgn(theDocument->hiliteRgn,theDocument->theTE);
  868.  
  869.     HiliteMenu(0);
  870.     
  871.     gCanUndoDrag = slCantUndo;
  872. }
  873.  
  874.